/**
 *  学习目标：Todos 案例
    需求1 - ✅完成组件拆分 
    需求2 - ✅列表渲染 
    需求3 - ✅更新一条数据
    需求4 - ✅删除一条数据
    需求5 - ✅点谁谁有边框
    需求6 - ✅切换数据
    需求7 - ✅统计剩余任务
    需求8 - ✅清除已完成
    需求9 - ✅改造Header为受控组件
    需求10 - ✅Header新增功能
    需求11 - ✅完善新增细节
    需求12 - ✅数据缓存功能
    需求13 - ✅小选影响全选
    需求14 - ✅全选影响小选
  
*/
import React from 'react';
import './styles/base.css';
import './styles/index.css';

export default class App extends React.Component {
  // 3.1 定义更新list的方法
  handleUpdate = (id) => {
    // 3.4 完成更新的逻辑
    const { list } = this.state;
    const newList = list.map((item) => ({
      ...item,
      isDone: item.id === id ? !item.isDone : item.isDone,
    }));
    this.setState({ list: newList });
  };

  // 4.1 App中定义删除方法
  handleDelById = (id) => {
    // 4.4完成删除逻辑 - 过滤出来不需要删的
    const list = this.state.list.filter((item) => item.id !== id);
    this.setState({ list });
  };

  // 5.5 定义修改type的方法
  handleToggleType = (type) => {
    this.setState({ type });
  };

  // 8.1 定义一个清除已完成的方法
  handleClear = () => {
    const { list } = this.state;
    this.setState({
      list: list.filter((item) => !item.isDone),
    });
  };

  // 10.3 定义新增方法
  handleAdd = (task) => {
    this.setState({ list: [{ id: Date.now(), task, isDone: false }, ...this.state.list] });
  };

  // 14.1 App中定义操作list的方法
  handleCheckAll = (e) => {
    // console.log('e.target.checked  ----->  ', e.target.checked);
    // 🔑 e.target.checked在用户点击时，得到与界面显示取反的值
    // 14.4 通过遍历覆盖每一项元素的isDone属性为e.target.checked
    this.setState({
      list: this.state.list.map((item) => {
        return {
          ...item,
          // 覆盖每项内容的isDone属性
          isDone: e.target.checked,
        };
      }),
    });
  };

  // 12. 1 在componentDidUpdate中监听数据变化
  componentDidUpdate() {
    // 12.2 存入本地缓存
    localStorage.setItem('todo-list', JSON.stringify(this.state.list));
    localStorage.setItem('todo-type', this.state.type);
  }

  // 2.1 声明state
  state = {
    // 12.3 从缓存中取出数据，作为默认值
    list: JSON.parse(localStorage.getItem('todo-list')) || [],
    type: localStorage.getItem('todo-type') || 'all',
    // 5.1 声明type状态
  };
  render() {
    const { list, type } = this.state;
    // 6.1 🔑定义一个计算属性
    const showList = list.filter((item) => {
      // 如果type的值为active，返回item.isDone 为false的
      if (type === 'active') {
        return !item.isDone;
      }
      // 如果type的值为completed，返回item.isDone 为true的
      if (type === 'completed') {
        return item.isDone;
      }

      // 如果type的值为all，返回item
      return item;
    });
    // 7.1  🔑计算剩余未完成任务的数组
    const restList = list.filter((item) => !item.isDone);

    // 12.1 计算isAll
    // 如果list为空，every方法直接返回true
    const isAll = list.length ? list.every((item) => item.isDone) : false;
    console.log('isAll  ----->  ', isAll);

    return (
      <section className="todoapp">
        {/* 头部 */}
        {/* 10.5 父传子调用新增方法 */}
        <Header handleAdd={this.handleAdd}></Header>
        {/* 主体 */}
        {/* 2.2 父传子list */}
        {/* 3.2 子传父技术，传回调 */}
        <Main
          // 12.2 传isAll给Main组件
          isAll={isAll}
          // 6.2 使用计算属性替换list
          list={showList}
          handleUpdate={this.handleUpdate}
          handleDelById={this.handleDelById}
          // 14.2 父传子回调函数
          handleCheckAll={this.handleCheckAll}
        ></Main>
        {/* 底部 */}
        {/* 5.2 父传子type */}
        {/* 7.2 传剩余长度 */}
        <Footer
          restLength={restList.length}
          type={type}
          handleToggleType={this.handleToggleType}
          // 8.2 子传父
          handleClear={this.handleClear}
        ></Footer>
      </section>
    );
  }
}

class Header extends React.Component {
  // 9.1 声明state
  state = {
    task: '',
  };

  handleKeyDown = (e) => {
    // 10.2 监听回车按键
    if (e.keyCode === 13) {
      // 11.3. 数据不能为空，提示用户
      if (!this.state.task.trim()) return alert('内容不能为空');
      this.props.handleAdd(this.state.task);
      // 11.2. 回车新增成功，新增空，清空输入框
      this.setState({ task: '' });
    }

    // 11.1. ESC取消输入内容
    if (e.keyCode === 27) {
      this.setState({ task: '' });
    }
  };
  render() {
    return (
      <header className="header">
        <h1>todos</h1>

        <input
          className="new-todo"
          placeholder="需要做什么"
          autoFocus
          // onChange配合setState改变状态
          onChange={(e) => this.setState({ task: e.target.value })}
          // 10.1 监听键盘事件
          onKeyDown={this.handleKeyDown}
          // 9.2 state控制value
          value={this.state.task}
        />
      </header>
    );
  }
}

class Main extends React.Component {
  render() {
    const { list, handleUpdate, handleDelById, isAll, handleCheckAll } = this.props;

    return (
      <section className="main">
        {/* 12.3 isAll控制checked属性 */}
        <input
          id="toggle-all"
          className="toggle-all"
          type="checkbox"
          checked={isAll}
          onChange={handleCheckAll}
        />
        <label htmlFor="toggle-all">全选</label>
        <ul className="todo-list">
          {/* 2.3. 列表渲染生成多个li */}
          {list.map((item) => {
            return (
              // 2.4. 设置key以及className、填入对应内容
              <li key={item.id} className={item.isDone ? 'completed' : ''}>
                <div className="view">
                  {/* 3.3 绑定onChange事件 */}
                  <input
                    className="toggle"
                    type="checkbox"
                    checked={item.isDone}
                    onChange={() => handleUpdate(item.id)}
                  />
                  <label>{item.task}</label>
                  {/* 4.3 绑定onClick事件 💥注意传参id */}
                  <button className="destroy" onClick={() => handleDelById(item.id)}></button>
                </div>
              </li>
            );
          })}
        </ul>
      </section>
    );
  }
}

class Footer extends React.Component {
  render() {
    const { type, handleToggleType, restLength, handleClear } = this.props;
    return (
      <footer className="footer">
        <span className="todo-count">
          {/* 7.3 显示内容 */}
          <strong>{restLength}</strong> 剩余
        </span>
        <ul className="filters">
          <li>
            {/* 5.3使用type分别和all 、selected、completed 做判断，同时只有一个表达式为真  */}
            <a
              // 5.4 绑定点击事件，传值type
              onClick={() => handleToggleType('all')}
              className={type === 'all' ? 'selected' : ''}
              href="#/"
            >
              全部
            </a>
          </li>
          <li>
            <a
              onClick={() => handleToggleType('active')}
              className={type === 'active' ? 'selected' : ''}
              href="#/active"
            >
              未完成
            </a>
          </li>
          <li>
            <a
              onClick={() => handleToggleType('completed')}
              className={type === 'completed' ? 'selected' : ''}
              href="#/completed"
            >
              已完成
            </a>
          </li>
        </ul>
        {/* 8.3 绑定onClick事件 */}
        <button onClick={handleClear} className="clear-completed">
          清除已完成
        </button>
      </footer>
    );
  }
}
